package com.qq.spirit.model;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XmlDataUtil
{

	static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	static DocumentBuilder builder = null;
	static
	{
		reinitDocumentBuilder();
	}

	private static void reinitDocumentBuilder()
	{
		try
		{
			builder = factory.newDocumentBuilder();
		} catch (ParserConfigurationException e)
		{
			reinitDocumentBuilder();
		}
	}

	/**
	 * 创建游戏数据结构
	 * 
	 * @param s
	 * @return
	 */
	public static XmlNodeData convertXmlToDataModel(String s)
	{
		XmlNodeData x = new XmlNodeData();
		if (s.equals(""))
		{
			return x;
		}
		if (!s.startsWith("<"))
		{
			String stemp = s.substring(0,20);
			if(stemp.indexOf("<") < 0)
			{
				return x;
			}
			s = s.substring(s.indexOf("<"));
		}
		try
		{
			x.setNodeName("root");
			ByteArrayInputStream bai = new ByteArrayInputStream(s.getBytes("utf-8"));
			Document document = builder.parse(bai);
			NodeList nL = document.getElementsByTagName("results");
			build(nL, x);
			x.setLoadSuc(true);
		} catch (Exception e)
		{
			// LoggerUtil.error(e);
		}

		return x;
	}

	private static void build(NodeList nL, XmlNodeData x)
	{
		if (nL == null || nL.getLength() == 0)
		{
			return;
		}

		for (int i = 0; i < nL.getLength(); i++)
		{
			Node node = nL.item(i);
			XmlNodeData c = new XmlNodeData();
			c.setNodeName(node.getNodeName());
			x.addChild(c);
			if (node.getChildNodes().getLength() > 1)
			{
				build(node.getChildNodes(), c);
			} else
			{
				// 判断第一个字节点下是否还有子节点
				if (node.hasChildNodes())
				{
					if (node.getFirstChild().hasChildNodes())
					{
						build(node.getChildNodes(), c);
					} else
					{
						c.setNodeValue(node.getTextContent());
					}
				} else
				{
					c.setNodeValue(node.getTextContent());
				}
			}
		}

	}

	/**
	 * 获取单个节点信息，此方法针对只有一个结果的情形
	 * 
	 * @param x
	 * @param s
	 * @return
	 */
	public static XmlNodeData getNodeInfo(XmlNodeData x, String s)
	{
		if (x == null || s == null)
		{
			return null;
		}

		List<XmlNodeData> s1 = getNodeInfoList(x, s);
		if (s1.isEmpty())
		{
			return null;
		}

		return s1.get(0);
	}

	/**
	 * 获得子节点信息，主要针对是子节点的情形
	 * 
	 * @param x
	 * @param s
	 * @return
	 */
	public static List<XmlNodeData> getNodeInfoList(XmlNodeData x, String s)
	{
		String[] s1 = s.split("[.]");
		List<String> l = new ArrayList<String>();
		for (String s2 : s1)
		{
			l.add(s2);
		}

		return getNodeInfo(x, l);
	}

	/**
	 * 获取单个节点内容，此方法针对只有一个结果的情形
	 * 
	 * @param x
	 * @param s
	 * @return
	 */
	public static String getNodeData(XmlNodeData x, String s)
	{
		if (x == null || s == null)
		{
			return "";
		}
		List<String> s1 = getNodeDataList(x, s);
		if (s1.isEmpty())
		{
			return "";
		}

		return s1.get(0);
	}

	/**
	 * 获得子节点值，针对叶节点情形
	 * 
	 * @param x
	 * @param s
	 * @return
	 */
	public static List<String> getNodeDataList(XmlNodeData x, String s)
	{
		List<String> sList = new ArrayList<String>();
		for (XmlNodeData x2 : getNodeInfoList(x, s))
		{
			sList.add(x2.getNodeValue());
		}
		return sList;
	}

	private static List<XmlNodeData> getNodeInfo(XmlNodeData x, List<String> s)
	{
		if (x == null || s == null)
		{
			return null;
		}

		List<XmlNodeData> resultStr = new ArrayList<XmlNodeData>();
		List<XmlNodeData> clist = new ArrayList<XmlNodeData>();
		clist.add(x);
		getNodeInfo(resultStr, clist, s, 0);

		return resultStr;
	}

	/**
	 * 递归查找节点
	 * 
	 * @param resultData
	 * @param nList
	 * @param s
	 */
	private static void getNodeInfo(List<XmlNodeData> resultData, List<XmlNodeData> nList, List<String> s, int i)
	{
		String sh = s.get(i);
		for (XmlNodeData cn : nList)
		{
			List<XmlNodeData> svlist = cn.getChildNodeData(sh);
			if (svlist.isEmpty())
			{
				continue;
			}
			if (s.size() > (i + 1))
			{
				getNodeInfo(resultData, svlist, s, i + 1);
			} else
			{
				resultData.addAll(svlist);
			}
		}
	}

	public static void main(String[] args)
	{
		try
		{
			BufferedReader f = new BufferedReader(new FileReader(new File("D:\\workspace\\astdGame\\conf\\caravan!getTradeInfo.action")));
			String line = null;
			String s1 = "";
			while ((line = f.readLine()) != null)
			{
				s1 += line;
			}
			// s1 =
			// "<?xml version=\"1.0\" encoding=\"UTF-8\"?><results><state>1</state><canrefresh>true</canrefresh><canbuy>false</canbuy><buycost>10</buycost><tradetimes>10</tradetimes><cangetmerchant>true</cangetmerchant><tradecombodto><type>1</type><info>巴蜀商人+淮南商人,大理商人+荆楚商人</info><discovered>1</discovered><discovername>本帅,暴君001</discovername></tradecombodto><tradecombodto><type>2</type><info>巴蜀商人+西域胡商+南越商人,辽东商人+淮南商人+楼兰商人</info><discovered>1</discovered><discovername>一路好走,天行健</discovername></tradecombodto><tradecombodto><type>3</type><info>,巴蜀商人+淮南商人+巴蜀商人+辽东商人</info><discovered>0</discovered><discovername>,轻舞飞扬</discovername></tradecombodto><refresh><textilemerchantid>8</textilemerchantid><state>2</state><name>淮南商人</name><effecttype>OverSeaTrade</effecttype><goldused>0</goldused><intro>有概率进行海外贸易，但是有可能被打劫</intro><pic>huainan</pic></refresh><refresh><textilemerchantid>10</textilemerchantid><state>0</state><name>南越商人</name><effecttype>RobberyP</effecttype><goldused>0</goldused><intro>大幅降低海外贸易被打劫率</intro><pic>nanyue</pic></refresh><refresh><textilemerchantid>11</textilemerchantid><state>0</state><name>浔阳商人</name><effecttype>Exp</effecttype><goldused>0</goldused><intro>增加纺织工人经验获得</intro><pic>xunyang</pic></refresh><recent><textilemerchantid>8</textilemerchantid><name>淮南商人</name><goldused>0</goldused><pic>huainan</pic></recent><recent><textilemerchantid>3</textilemerchantid><name>巴蜀商人</name><goldused>0</goldused><pic>bashu</pic></recent></results>";

			XmlNodeData battleMultiInfo = convertXmlToDataModel(s1);
			// doCall(null, battleMultiInfo);
		} catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
